Home |
| Latest | About | Random
# Week 4 Wednesday Dear Class, Today we start section 9, **fun with functions!** We will go through functions in several phases, first a simple overview, then more nuances of them in future lectures. Already with handling input/output, storing data, and control flow, you can write "all" programs a computer can perform. **Being able to write and use functions makes your program even more powerful! Often programs consist of mostly functions!** Section 9 is not tested on Exam 1, but we continue to build everything up from what we have learned so far. For Exam 1, I've started a [[1-teaching/ucla-2026-fall-pic-10a/laundry-list|laundry-list]] of things we've discussed. You should make yourself a laundry list as well. This of course is not enough, you should read and write code with them to practice! (**Perhaps you all can collaborate amongst yourselves and make a communal list**!) Also, there will be **no notes, closed book, no technology, no cheating, no shenanigans** for the exam. Bring your own **pencil or pen**, as you will be writing your responses on sheets of paper provided to you. The exam is **50 minutes** in class, about **3 to 4 problems, some may have multiple parts.** It covers up to and including **section 8**, homework up to and including **HW3**, and the lectures we have done so far. Your **HW3** is **due this Friday at 10pm**. -- B. . . . . **Here's a birthday card for anyone who has a birthday!** ![[1-teaching/ucla-2026-fall-pic-10a/---files/Pasted image 20261021070756.png]] ## Functions -- A first look. ### But first... Is it anyone's birthday? **Raise your hand if your birthday is this month!** Let's all sing happy birthday to them! ``` Happy birthday to you! Happy birthday to you! Happy birthday dear [their name]! Happy birthday to you! ``` And again! . . . . . ## Function to abstract away repeated task. Suppose we want to write a program that sings happy birthday to each person `A`, `B`, `C`, ... with a birthday. It will be laborious to write out a song each time for each person individually. Not that we don't want to, of course... So instead, we write a **function**, that is like a *factory* or *machine*, where it either **does something**, or **outputs something**, or **both**. In this case we take in the birthday star's name as input and we print a song out with their name! Perhaps we call our function `sing`, and perhaps it takes in a `string` as input for a person's name, and all it does is print to the screen the song. To accomplish what we want, we will discuss how to - **Declare** a function, - **Define** a function, and - **Call** a function . . . . . ## Declaring a function. To do this, like a variable before, we have to **declare** it before we use it. And since we anticipate using it in `main`, we need to declare it before `main`, like this ```cpp #include #include using namespace std; void sing(string person); // declaring our function int main() { return 0; } ``` Note the function `sing` has the word `void` in front of it, this is its **return type**. - Often a function returns a value, so the type of the value goes in front of the name of the function when we declare it. - This return value can be assigned to another variable later. You can think of this return value as the **output** of this function. - `int my_function(...);` declares a function that will return an `int`. - `string my_other_function(...);` declares a function that will return a `string`. - To return the value `x`, we use the `return` keyword by writing `return x;` - The function ends immediately when it reaches the `return` keyword, and control goes back to where the function was called. - We will return to `return` later. Ha-ha! - If the function does not return anything, then its return type is `void`. Our `sing` function will only perform an action (print to the console), but it will not give back a value. Now, in this function declaration `void sing(string person);`, we also indicated the type of the input as well, in this case it is a `string`. The name of the input here is called `person`. - This variable is called a **parameter** of this function. - During declaration of a function, you do not need to specify the name of the parameter, just the type suffices. So `void sing(string);` is a valid declaration. - This line `void sing(string person)` is also known as the **function signature** of this function. It tells us the (1) name of the function, (2) the return type of the function, and (3) the types and number of parameters for this function. - According to the book, this is the function signature. (Which is fine for our purpose in our class.) . . . . . ## Defining a function. Now that we have declared our function `sing`, we need to **define** what it does. We use braces `{` and `}` to define the action of this function. - You can **declare and define all together at the top**: ```cpp #include #include using namespace std; void sing(string person) { // declare and define together // some action! } int main() { return 0; } ``` - Note when you define a function, you need to name the parameter if you want to use it inside the function body. - Or, you can **declare** at the top first, then **define** the function later after the `main`: ```cpp #include #include using namespace std; void sing(string person); // declare first int main() { return 0; } void sing(string person) { // define later // some action! } ``` Ok, now let's write something that this `sing` function should do, namely, sing the happy birthday song to `person`! ```cpp void sing(string person) { for (int i = 0; i < 10; ++i){ cout << "~ * ";} cout << endl; cout << "Happy birthday to you!" << endl; cout << "Happy birthday to you!" << endl; cout << "Happy birthday dear " << person << "!" << endl; cout << "Happy birthday to you!" << endl; } ``` . . . . . ## Calling a function. Now that we have our `sing` function declared and defined, it is time to use it in `main`. - To **call** the function we write `sing(argument)` and we pass in an **argument** for the parameter of the function. - We must have the parentheses `(` and `)` to call a function, even if that function has no parameters! ```cpp #include #include using namespace std; void sing(string person); int main() { sing("Joe Bruin"); // Calling the function sing("Oski the Bear"); // Calling the function return 0; } void sing(string person) { for (int i = 0; i < 10; ++i){ cout << "~ * ";} cout << endl; cout << "Happy birthday to you!" << endl; cout << "Happy birthday to you!" << endl; cout << "Happy birthday dear " << person << "!" << endl; cout << "Happy birthday to you!" << endl; } ``` **Important.** The word **parameter** refers to the variable used in the function scope, while **argument** refers to the thing that you assign to the parameters. - `"Joe Bruin"` is the argument. - `string person` is the parameter of this `sing` function. - Doing `sing("Joe Bruin")` assigns the argument `"Joe Bruin"` to the parameter `person`. ### Scope of a function. But where does the parameter `string person` exist during all of this? - Each time the function is called, a **function scope** is created. (Draw a dashed box to represent this!) - And as the function scope is created, the first thing that happens is **each parameter variable is declared and assigned to the values given by the arguments**. - The corresponding argument is assigned to the corresponding parameter in the list indicated by the function signature. - When the function ends, each parameter and variable declared in this function scope is **destroyed**. - Now, **unlike a typical scope with braces**, a function scope is different in that it **cannot** access variables outside of its function scope. - So the best way to allow the function to use something from the outside is to have a parameter and pass the outside data in as an argument. - (Note. There is something called global variables which functions can reach on the outside, but we will not discuss that.) . . . . . ## A mystery -- An 1D automaton. ### Part 1. A mysterious rule90.... Let us write a function that is not a `void` function, but actually returns something out. I have a mysterious function in mind, call it `rule90`. This function **transforms** a string into another string. - It will take in a `string` consisting only of space character `' '` and the character `'a'`. - Like `"aa a a aa aaaa a aaaaa"` - Or `"aaaaaaaaaaaaaaaaaaaaaa"` - Or `" a "` - It will **return** a `string` according to the following rule: If the input parameter is `string s`: - We return a `string t` that has the same length as `s`, - The `0`-th index and the last index character of `t` is the same as `s` - For index `i` character of `t`, where `i > 0` and `i < s.length() - 1` (so `i` is strictly in the middle) - If `s.at(i-1)` and `s.at(i+1)` are *different*, then `t.at(i)` is the character `'a'`. - Otherwise `t.at(i)` is the space character `' '`. For example, ``` s = "aa a a a" becomes t = "aaaa a" ``` Let us write it up! Note we use `return` keyword to return the desired output of this function. ```cpp #include #include using namespace std; // declare our function rule90 here. What is its function signature? int main() { cout << rule90("aa a a a") << endl; // If done right, we // expect "aaaa a" return 0; } // define our function rule90 here. Make it return a string // using the return keyword. ``` ### Part 2. What if we use it repeatedly...??? Here is something curious about `rule90`. Let us try putting back in `rule90` what it gave us, repeatedly so. Say do it `100` times. And we `cout` the result each time. To do this we should create a `string` variable to hold this value and all its future updates. This loop would do: ```cpp string s = "aa a a a"; for (int i = 0 ; i < 100; ++i) { cout << s << endl; s = rule90(s); } ``` Try different starting argument `string s`! - Try very random ones like `string s = " a aaa a a a a aa a a a a"` - What do you get with `string s = " a "`? **Curious!** ---